<template>
  <div class="dashboard-container">
    <div class="app-container">
      <el-card>
        <el-tabs>
          <!-- 放置页签 -->
          <el-tab-pane label="角色管理">
            <!-- 新增角色按钮 -->
            <el-row style="height:60px">
              <el-button
                icon="el-icon-plus"
                size="small"
                type="primary"
                @click="hAdd"
              >新增角色</el-button>
            </el-row>
            <!-- 表格 -->
            <el-table border stripe :data="roles">
              <el-table-column label="序号" width="120" type="index" />
              <el-table-column label="角色名称" width="240" prop="name" />
              <el-table-column label="描述" prop="description" />
              <el-table-column label="操作">
                <template slot-scope="scope">

                  <el-button size="small" type="success" @click="hAssgin(scope.row.id)">分配权限</el-button>
                  <el-button size="small" type="primary" @click="hEdit(scope.row)">编辑</el-button>
                  <el-button size="small" type="danger" @click="hdel(scope.row.id)">删除</el-button>
                </template>
              </el-table-column>
            </el-table>

            <el-row type="flex" justify="center" align="middle" style="height: 60px">
              <!-- 分页组件 -->
              <el-pagination
                :current-page.sync="q.page"
                :page-size="q.pagesize"
                :page-sizes="[2,3,5,10]"
                layout="total, sizes, prev, pager, next, jumper"
                :total="total"
                @size-change="handleSizeChange"
                @current-change="handleCurrentChange"
              />
            </el-row>
          </el-tab-pane>
        </el-tabs>
      </el-card>
    </div>
    <!-- 新增弹框 -->
    <el-dialog
      :title="isEdit ? '编辑角色信息':'新增角色信息'"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :visible.sync="showDialog"
      @closed="hclose"
    >

      <!--   -->
      <el-form ref="roleForm" :model="roleForm" :rules="rules" label-width="100px">
        <el-form-item label="角色名称" prop="name">
          <el-input v-model="roleForm.name" />
        </el-form-item>
        <el-form-item label="角色描述" prop="description">
          <el-input v-model="roleForm.description" />
        </el-form-item>
      </el-form>
      <!-- 底部 -->
      <el-row slot="footer" type="flex" justify="center">
        <el-col :span="6">
          <!-- 对话框隐藏时, 会自动触发 closed事件 -->
          <el-button size="small" @click="showDialog = false">取消</el-button>
          <el-button size="small" type="primary" @click="hSubmit">确定</el-button>
        </el-col>
      </el-row>
    </el-dialog>

    <el-dialog
      title="分配角色"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :visible.sync="showDialogAssign"
    >
      <AssginPermission v-if="showDialogAssign" :role-id="roleId" @close="showDialogAssign=false" />
    </el-dialog></div>
</template>

<script>
import { getRoles, delRoles, addRoles, updateRole } from '@/api/roles'
import AssginPermission from './assginPermission.vue'
export default {
  name: 'Settings',
  components: {
    AssginPermission
  },
  data() {
    return {
      isEdit: null,
      q: { // 发请求需要的 query参数
        page: 1, // 页码
        pagesize: 2 // 每页条数
      },
      roles: [], // 角色列表
      total: 0, // 角色总数量
      showDialog: false, // 对话框 显示隐藏
      roleForm: { // 新增角色 / 数据回填
        name: '',
        description: '' // java线上接口 是region
      },
      rules: {
        name: [{ required: true, message: '角色名称不能为空', trigger: 'blur' }]
      },
      showDialogAssign: false,
      roleId: ''
    }
  },
  created() {
    this.loadRoles()
  },
  methods: {
    async loadRoles() { // 获取角色列表信息
      try {
        const res = await getRoles(this.q) // 不传参数默认,获取所有的角色信息
        // console.log(res)
        this.roles = res.data.rows
        this.total = res.data.total
      } catch (e) {
        console.log('获取角色列表失败:' + e)
      }
    },
    handleSizeChange(val) { // 每页条数改变时,发请求
      console.log('每页显示条数:' + val)
      this.q.pagesize = val
      this.loadRoles()
    },
    handleCurrentChange(val) { // 当前页改变时,发请求
      console.log('当前页码:' + val)
      this.q.page = val
      this.loadRoles()
    },
    async hdel(id) { // 点击删除角色
      // // 方案1: try-catch
      // this.$confirm('确定要删除该角色吗?', '提示', {
      //   type: 'warning'
      // })
      //   .then(async() => {
      //     try {
      //       const res = await delRoles(id)
      //       this.$message.success(res.message)
      //       this.loadRoles()
      //     } catch (e) {
      //       this.$message.error(e.message)
      //     }
      //   })
      //   .catch(e => {})

      // 方案2: await + .catch
      // await + .catch  点击确定角色.then()  点击取消就等于 .catch().then() ,原理如下:
      // ★因为 在 Promise 的串行任务中, 每一次回调函数(包括 .then 和 .catch)中返回的结果, 会作为下一个 .then 的参数
      const result = await this.$confirm('确定要删除该角色吗?', '提示', {
        // $confirm 内部封装的Promise 确定返回 confirm, 取消返回 cancel
        type: 'warning'
      }).catch(e => e) // 点击取消会 return cancel
      if (result !== 'confirm') return // 点击取消直接 return

      const res = await delRoles(id).catch(e => this.$message.error(e.message)) // 这里也可以直接.catch
      this.$message.success(res.message)
      // 4. 处理分页的问题: 最后一页只有一个元素时
      // 所有分页的删除 Bug 都是这么处理
      if (this.roles.length === 1 && this.q.page > 1) {
        this.q.page--
      }
      this.loadRoles()
      /* 1. 点击删除 弹出确认框
         2. 点击确定 发送删除角色请求
         3. 提示用户
         4. 如果最后一页 [只剩下一条数据] 并且 [不是第一页] 就让当前页-1
         5. 重新 获取角色列表信息  */
    },
    hAdd() { // 点击添加 弹出对话框
      this.showDialog = true
      this.isEdit = false
    },
    hEdit(row) { // 点击编辑 弹出对话框 ; 作用域插槽 深拷贝 实现数据回填
      this.showDialog = true
      this.isEdit = true
      // 一定要使用深拷贝,  否则在编辑的过程中, 列表的数据也会发生改变
      this.roleForm = { ...row }
    },
    async doAdd() { // 添加对话框 点击确定
      // validate() 不传参 返回的是一个Promise对象, 所以也可使用 await + .catch
      // const valid = await this.$refs.roleForm.validate().catch(e => e)
      // if (!valid) return // valid 是一个布尔值
      const res = await addRoles(this.roleForm).catch(e => this.$message.error(e.message))
      this.$message.success(res.message)
      // 添加成功后, 自动跳转至最后一页 (也可以使用计算属性)
      // const lastPage = Math.ceil(this.total / this.q.pagesize) // 最后一页

      // // 当前最后一页是否 "满了" , total % pagesize ===0
      // if (this.total % this.q.pagesize === 0) {
      //   this.total++ // 如果使用计算属性 需要和下行代码 换位置
      //   this.q.page = lastPage + 1 // 最后一页+1 之前 必须让 total+1 ★只有总数增加,页码才会增加
      // } else {
      //   this.q.page = lastPage
      // }

      // 优化版
      // this.total++
      this.q.page = Math.ceil(++this.total / this.q.pagesize)
      this.loadRoles()

      this.showDialog = false
      this.$refs.roleForm.resetFields()
    },
    async doEdit() { // 编辑对话框 点击确定
      const res = await updateRole(this.roleForm).catch(e => this.$message.error(e.message))
      this.$message.success(res.message)
      this.loadRoles()
      this.showDialog = false
    },
    async hSubmit() { // 确定按钮  1.表单校验 2.判断是 添加还是编辑操作
      // 公共兜底校验 validate() 不传参 返回的是一个Promise对象, 所以也可使用 await + .catch
      const valid = await this.$refs.roleForm.validate().catch(e => e)
      if (!valid) return // valid 是一个布尔值
      this.isEdit ? this.doEdit() : this.doAdd()
    },
    hclose() { // 对话框关闭时, 清空表单数据 , 清除校验规则
      // resetFields() 这个不是做清空表单数据的API
      // resetFields(): 重置所有数据项, 还原成 "默认值", ElementUI 认为第一次赋值的内容是默认值
      this.roleForm = {
        name: '',
        description: ''
      }
      // 两种方法都可以清除 校验规则  (原因: 添加出现红字后 ,关闭对话框, 点击编辑 红字依然存在)
      // this.$refs.roleForm.resetFields()
      this.$refs.roleForm.clearValidate()
    },
    hAssgin(id) { // 作用域插槽  id传给子组件
      this.roleId = id
      this.showDialogAssign = true
    }

  }
}
</script>
